using System.Collections.Generic;
using System;
using System.IO;

namespace Framework
{
    public static partial class Utils
    {
        public static class Text
        {
            // [ThreadStatic]
            public static System.Text.StringBuilder CachedStringBuilder = new System.Text.StringBuilder(1024);
            public static void AppendString(string value, bool isPath = false, bool clear = false)
            {
                if (clear)
                {
                    CachedStringBuilder.Clear();
                }
                if (isPath)
                {
                    var len = value.Length - 1;
                    for (int i = 0; i <= len; i++)
                    {
                        var cv = value[i];
                        if (i == len)
                        {
                            if (cv == '/' || cv == '\\') continue;
                        }
                        CachedStringBuilder.Append(cv);
                    }
                    CachedStringBuilder.Append('/');
                }
                else
                {
                    CachedStringBuilder.Append(value);
                }
            }
            public static string GetAppendString()
            {
                var value = CachedStringBuilder.ToString();
                CachedStringBuilder.Clear();
                return value;
            }
            /// <summary>
            /// 获取格式化字符串。
            /// </summary>
            /// <param name="format">字符串格式。</param>
            /// <param name="arg0">字符串参数 0。</param>
            /// <returns>格式化后的字符串。</returns>
            public static string Format(string format, object arg0)
            {
                if (format == null)
                {
                    throw new Exception("Format is invalid.");
                }
                CachedStringBuilder.Length = 0;
                CachedStringBuilder.AppendFormat(format, arg0);
                return CachedStringBuilder.ToString();
            }

            /// <summary>
            /// 获取格式化字符串。
            /// </summary>
            /// <param name="format">字符串格式。</param>
            /// <param name="arg0">字符串参数 0。</param>
            /// <param name="arg1">字符串参数 1。</param>
            /// <returns>格式化后的字符串。</returns>
            public static string Format(string format, object arg0, object arg1)
            {
                if (format == null)
                {
                    throw new Exception("Format is invalid.");
                }
                CachedStringBuilder.Length = 0;
                CachedStringBuilder.AppendFormat(format, arg0, arg1);
                return CachedStringBuilder.ToString();
            }

            /// <summary>
            /// 获取格式化字符串。
            /// </summary>
            /// <param name="format">字符串格式。</param>
            /// <param name="arg0">字符串参数 0。</param>
            /// <param name="arg1">字符串参数 1。</param>
            /// <param name="arg2">字符串参数 2。</param>
            /// <returns>格式化后的字符串。</returns>
            public static string Format(string format, object arg0, object arg1, object arg2)
            {
                if (format == null)
                {
                    throw new Exception("Format is invalid.");
                }
                CachedStringBuilder.Length = 0;
                CachedStringBuilder.AppendFormat(format, arg0, arg1, arg2);
                return CachedStringBuilder.ToString();
            }

            /// <summary>
            /// 获取格式化字符串。
            /// </summary>
            /// <param name="format">字符串格式。</param>
            /// <param name="args">字符串参数。</param>
            /// <returns>格式化后的字符串。</returns>
            public static string Format(string format, params object[] args)
            {
                if (format == null)
                {
                    throw new Exception("Format is invalid.");
                }
                if (args == null)
                {
                    throw new Exception("Args is invalid.");
                }
                CachedStringBuilder.Length = 0;
                CachedStringBuilder.AppendFormat(format, args);
                return CachedStringBuilder.ToString();
            }

            /// <summary>
            /// 根据类型和名称获取完整名称。
            /// </summary>
            /// <typeparam name="T">类型。</typeparam>
            /// <param name="type">名称。</param>
            /// <returns>完整名称。</returns>
            public static string GetFullTypeName<T>(string type)
            {
                return GetFullTypeName(typeof(T), type);
            }

            /// <summary>
            /// 根据类型和名称获取完整名称。
            /// </summary>
            /// <param name="type">类型。</param>
            /// <param name="name">名称。</param>
            /// <returns>完整名称。</returns>
            public static string GetFullTypeName(Type type, string name)
            {
                if (type == null)
                {
                    throw new Exception("Type is invalid.");
                }
                string typeName = type.FullName;
                return string.IsNullOrEmpty(name) ? typeName : Format("{0}.{1}", typeName, name);
            }

            public static string FirstCharUpper(string value)
            {
                if (string.IsNullOrEmpty(value)) return string.Empty;
                if (value.Length < 2) return value.ToUpper();
                return value.Substring(0, 1).ToUpper() + value.Substring(1);
            }
            private static readonly List<string> _stackTraceInfo = new(10);
            public static List<string> GetStackTraceInfo(int startFrame = 1, int count = 1)
            {
                _stackTraceInfo.Clear();
                var trace = new System.Diagnostics.StackTrace(true);
                if (startFrame < 1)
                {
                    startFrame = 1;
                }
                startFrame++;
                var len = trace.FrameCount;
                if (count < 1) count = 1;
                var c = 0;
                for (int i = startFrame; i < len; i++)
                {
                    var f = trace.GetFrame(i);
                    var line = f.GetFileLineNumber();
                    if (line < 1) continue;

                    var file = Path.GetFileName(f.GetFileName());
                    var method = f.GetMethod().Name;
                    _stackTraceInfo.Add(string.Format("[{1}] {0} : {2}", file, line, method));
                    c++;
                    count--;
                    if (count < 1)
                    {
                        break;
                    }
                }
                return _stackTraceInfo;
            }
        }
    }
}